package 剑指Offer.简单;

/**
 * 输入一个矩阵，按照从外向里以顺时针的顺序依次打印出每一个数字。
 * <p>
 *  
 * <p>
 * 示例 1：
 * <p>
 * 输入：matrix = [[1,2,3],[4,5,6],[7,8,9]]
 * 输出：[1,2,3,6,9,8,7,4,5]
 * 示例 2：
 * <p>
 * 输入：matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
 * 输出：[1,2,3,4,8,12,11,10,9,5,6,7]
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/shun-shi-zhen-da-yin-ju-zhen-lcof
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 *
 * @author caihe
 * @date 2022/8/23 10:54
 */
public class _29顺时针打印矩阵 {

    public static void main(String[] args) {
        _29顺时针打印矩阵 a = new _29顺时针打印矩阵();
        int[][] aaa = new int[][]{
                {1, 2, 3, 4},
                {5, 6, 7, 8},
                {9, 10, 11, 12},
                {13, 14, 15, 16}};
        a.spiralOrder(aaa);
    }

    public int[] spiralOrder(int[][] matrix) {
        if (matrix.length == 0 || matrix[0].length == 0) {
            return new int[0];
        }

        // 计算每层的长度
        int xLen = matrix.length - 1;
        int yLen = matrix[0].length - 1;
        // 节点数
        int count = Math.multiplyExact(matrix.length, matrix[0].length);
        int index = 0;
        int[] res = new int[count];
        int x = 0, y = -1;
        while (index < count) {
            // 特殊处理每层的第一个节点 后续的长度一致
            res[index++] = matrix[x][++y];
            // 右
            for (int i = 0; i < yLen && index < count; i++) {
                res[index++] = matrix[x][++y];
            }
            // 下
            for (int i = 0; i < xLen && index < count; i++) {
                res[index++] = matrix[++x][y];
            }
            // 左
            for (int i = 0; i < yLen && index < count; i++) {
                res[index++] = matrix[x][--y];
            }
            // 上
            for (int i = 0; i < xLen - 1 && index < count; i++) {
                res[index++] = matrix[--x][y];
            }
            // 每层遍历完后 需要维护每层的长度-2 因为一圈有两层
            xLen -= 2;
            yLen -= 2;
        }
        return res;
    }

}
